﻿using System;

namespace CodeContrib.Web.Routing
{
	public class TenantRouteInfo
	{
		private bool _needsRewrite;
		private string _slug;
		private readonly int _tenantId;
		private Uri _uri;
		private string _url;

		public int TenantId
		{
			get { return _tenantId; }
		}

		public string Url
		{
			get { return _url; }
			set
			{
				_uri = new Uri(value);

				_url = value;
			}
		}

		public TenantRouteInfo(int tenantId, string url) : this(tenantId, url, null)
		{
		}

		public TenantRouteInfo(int tenantId, string url, string slug)
		{
			_tenantId = tenantId;
			Url = url;

			UpdateSlug(slug);
		}

		public bool HasHigherPriority(TenantRouteInfo other)
		{
			return (Url.Length > other.Url.Length);
		}

		public bool HasSameHost(TenantRouteInfo other)
		{
			var uri = new Uri(other.Url);

			return (uri.Authority == _uri.Authority);
		}

		public bool Match(Uri uri)
		{
			if (_uri.Authority != uri.Authority
			    || _uri.Segments.Length > uri.Segments.Length)
			{
				return false;
			}

			for (var i = 0; i < _uri.Segments.Length; i++)
			{
				if (uri.Segments[i].TrimEnd('/')
				    != _uri.Segments[i].TrimEnd('/'))
				{
					return false;
				}
			}

			return true;
		}

		public string RewriteInbound(string url)
		{
			var urlLength = (_needsRewrite) ? Url.Length : Url.Length - _slug.Length;

			var inboundUrl = new Uri(url).ToString().Substring(urlLength);
			inboundUrl = inboundUrl.TrimStart('/');

			if (_needsRewrite)
			{
				inboundUrl = _slug + "/" + inboundUrl;
			}

			return "~/" + inboundUrl;
		}

		public string RewriteOutbound(string url)
		{
			if (!_needsRewrite)
			{
				return url;
			}

			if (string.IsNullOrEmpty(url) || url == "/"
			    || url.Length < (_slug.Length + 1))
			{
				return string.Empty;
			}

			return url.Substring(_slug.Length + 1);
		}

		private void UpdateSlug(string slug)
		{
			_slug = string.IsNullOrEmpty(slug) ? "default" : slug.Trim('/');

			_needsRewrite = (_uri.Segments[_uri.Segments.Length - 1] != _slug);
		}
	}
}